package logica.persistencia;

import java.util.LinkedList;
import java.util.List;

import logica.EntidadRol;
import logica.Relacion;
import logica.RelacionException;

import org.jdom.Element;

import borrador.grafica.TransformadorAGraficable;

import vista.objetos.AtributoGraficable;
import vista.objetos.AtributoTipoNoSoportadoException;
import vista.objetos.EntidadRolGraficable;
import vista.objetos.EstrategiaRelacionGraficable;
import vista.objetos.GraficableConEtiqueta;
import vista.objetos.NoEsObjetoDiagramableException;
import vista.objetos.RelacionGraficable;
import xml.ConstantesXml;

public class RelacionGraficablePersistente extends GraficableConEtiquetaPersistente {
	public RelacionGraficablePersistente(
			GraficableConEtiqueta _graficableConEtiqueta) {
		super(_graficableConEtiqueta);
	}

	@Override
	public void serializar() {
		Element elementoRelacion = new Element (ConstantesXml.ELEMENTO_RELACION);
		Relacion relacion;
		try {
			relacion = (Relacion)this.getGraficableConEtiqueta().getObjetoDiagramaDecorado();
			super.serializarGenerico(relacion, elementoRelacion);
			RelacionGraficable reG = (RelacionGraficable) this.getGraficableConEtiqueta();
			AtributoGraficablePersistente.serializarAtributos(reG.getAtributos(), elementoRelacion);	
			serializarEntidadesRol(elementoRelacion, relacion, reG);
			serializarEstategia(elementoRelacion, reG);
		} catch (NoEsObjetoDiagramableException e) {
			
			e.printStackTrace();
		}
		
		this.getElementoPadre().addContent(elementoRelacion);
		
	}
	
	static public void serializarEstategia (Element elementoRelacion, RelacionGraficable relacionGraficable) {
		EstrategiaRelacionGraficable tipo = relacionGraficable.getTipo();
		String tipoString = tipo.getClass().getName();
		elementoRelacion.setAttribute(ConstantesXml.TIPO_ESTRATEGIA, tipoString);
	}
	
	static public void hidratarEstategia (Element elementoRelacion, RelacionGraficable relacionGraficable) {
		String tipoString = elementoRelacion.getAttributeValue(ConstantesXml.TIPO_ESTRATEGIA);
		Class<?> c = null;
		try {
			c = Class.forName(tipoString);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		EstrategiaRelacionGraficable tipo = null;
		try {
			tipo = (EstrategiaRelacionGraficable) c.newInstance();
			relacionGraficable.setTipo(tipo);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}			
	}
	
	static public void serializarEntidadesRol(Element elementoRelacion,
			Relacion relacion, RelacionGraficable regG) {
		if (relacion.getReferenciaAEntidadesExternas().size() > 0) {
			Element listaEntidadesRol = new Element (ConstantesXml.LISTA_ENTIDAD_ROL);
			
			for (EntidadRolGraficable entidadRG : regG.getReferenciasExternas()) {
				EntidadRolGraficablePersistente entRolGP = new EntidadRolGraficablePersistente(entidadRG);
				entRolGP.setElementoPadre(listaEntidadesRol);
				entRolGP.serializar();
			}
			elementoRelacion.addContent(listaEntidadesRol);
			
		}
	}

	@Override
	public void hidratar() {
		super.hidratarGenerico(this.getElementoGraficable());
		RelacionGraficable reG = (RelacionGraficable) this.getGraficableConEtiqueta();
		
		Relacion relacion= (Relacion)reG.getObjetoDiagramaDecorado();
		List<AtributoGraficable> atributos = null;
		try {
			atributos = TransformadorAGraficable.getAtributoGraficables(relacion.getAtributos());
			AtributoGraficablePersistente.hidratarAtributos(atributos,reG, this.getElementoGraficable());
		} catch (AtributoTipoNoSoportadoException e) {
			e.printStackTrace();
		}
		
		List<EntidadRolGraficable> entidadesRG = getEntidadRolGraficables(relacion.getEntidades(), this.getElementoGraficable());
		try {
			reG.setEntidadesRol(entidadesRG);
		} catch (RelacionException e) {
			e.printStackTrace();
		}
		
		hidratarEstategia(this.getElementoGraficable(), reG);
	}

	public static List<EntidadRolGraficable> getEntidadRolGraficables(List<EntidadRol> entidadRoles, Element elementoGraficable) 
	{
		
		List<EntidadRolGraficable> entidadesRolesGraficables = new LinkedList<EntidadRolGraficable>();
		Element listaElementosEntidades = elementoGraficable.getChild(ConstantesXml.LISTA_ENTIDAD_ROL);
		
		if (listaElementosEntidades != null) {
			@SuppressWarnings("unchecked")
			List<Element> elementosEntidadesRol = listaElementosEntidades.getChildren(ConstantesXml.ELEMENTO_ENTIDAD_ROL);
				
			for (Element elementoEntidadRol : elementosEntidadesRol) {
				
				EntidadRolGraficablePersistente entRGP = new EntidadRolGraficablePersistente(elementoEntidadRol);
				entRGP.hidratar();
				

				if (entRGP.getGraficableConEtiqueta() != null) {
					EntidadRolGraficable entidadRG = (EntidadRolGraficable) entRGP.getGraficableConEtiqueta();
					entidadesRolesGraficables.add(entidadRG);
				}
			}
		}
		return entidadesRolesGraficables;
	}


}
